#include "img_viewer.h"

img_Viewer::img_Viewer(vtkRenderWindow *_axial,
                       vtkRenderWindow *_coronal,
                       vtkRenderWindow *_sagittal,
                       vtkRenderWindow *_3DSlice, vtkRenderWindow *_3DInfection, QObject *parent)
    : QObject(parent)
    , m_axialWidget(new img_Widget(_axial, img_Widget::AXIAL, this))
    , m_coronalWidget(new img_Widget(_coronal, img_Widget::CORONAL, this))
    , m_sagittalWidget(new img_Widget(_sagittal, img_Widget::SAGITTAL, this))
    , m_3DSlice(_3DSlice)
    , m_3DInfection(new img_3DInfection(_3DInfection, this))
    , m_render(vtkSmartPointer<vtkRenderer>::New())
    , m_callback(vtkSmartPointer<vtkCallback>::New())
    , m_axes(vtkSmartPointer<vtkAxesActor>::New())
{
    init3DWidget();
    initCallback();
    initConnect();
}

void img_Viewer::setImg(img_File * img)
{
    this->m_img = img;
    this->m_render->SetBackground(0.1, 0.1, 0.1);
    //初始化三视图显示
    this->m_axialWidget->setImg(img);
    this->m_coronalWidget->setImg(img);
    this->m_sagittalWidget->setImg(img);
    //3D坐标轴长度
    this->m_axes->SetTotalLength(m_img->info().dim[1]*m_img->info().pixdim[1] + 50,
                                 m_img->info().dim[2]*m_img->info().pixdim[2] + 50,
                                 m_img->info().dim[3]*m_img->info().pixdim[3] + 50);
    //更新3D视图
    reset3D();
}

void img_Viewer::setAnalysisImg(vtkImageData *img)
{
    m_axialWidget->setAnalysisImg(img);
    m_coronalWidget->setAnalysisImg(img);
    m_sagittalWidget->setAnalysisImg(img);
}

void img_Viewer::unSetAnalysisImg()
{
    m_axialWidget->unSetAnalysisImg();
    m_coronalWidget->unSetAnalysisImg();
    m_sagittalWidget->unSetAnalysisImg();
}

void img_Viewer::set3DInfection(vtkImageData *img)
{
    if(!m_3DInfection->isSet()) {
        m_3DInfection->set3DInfection(img);
    }
}

void img_Viewer::unSet3DInfection()
{
    m_3DInfection->clear();
}

void img_Viewer::setPositionX(int _x)
{
    m_sagittalWidget->getImageViewer()->SetSlice(_x);
    m_sagittalWidget->getAnalysisViewer()->SetSlice(_x);
    double center[3] = {0.0};
    //----------------------------------------------------------
    m_axialWidget->getCrossLine()->getCenter(center);
    center[0] = _x * m_img->info().pixdim[1];
    m_axialWidget->getCrossLine()->setCenter(center);
    m_axialWidget->getImageViewer()->Render();
    //----------------------------------------------------------
    m_coronalWidget->getCrossLine()->getCenter(center);
    center[0] = _x * m_img->info().pixdim[1];
    m_coronalWidget->getCrossLine()->setCenter(center);
    m_coronalWidget->getImageViewer()->Render();
}

void img_Viewer::setPositionY(int _y)
{
    m_coronalWidget->getImageViewer()->SetSlice(_y);
    m_coronalWidget->getAnalysisViewer()->SetSlice(_y);
    double center[3] = {0.0};
    //----------------------------------------------------------
    m_axialWidget->getCrossLine()->getCenter(center);
    center[1] = _y * m_img->info().pixdim[2];
    m_axialWidget->getCrossLine()->setCenter(center);
    m_axialWidget->getImageViewer()->Render();
    //----------------------------------------------------------
    m_sagittalWidget->getCrossLine()->getCenter(center);
    center[1] = _y * m_img->info().pixdim[2];
    m_sagittalWidget->getCrossLine()->setCenter(center);
    m_sagittalWidget->getImageViewer()->Render();
}

void img_Viewer::setPositionZ(int _z)
{
    m_axialWidget->getImageViewer()->SetSlice(_z);
    m_axialWidget->getAnalysisViewer()->SetSlice(_z);
    double center[3] = {0.0};
    //----------------------------------------------------------
    m_sagittalWidget->getCrossLine()->getCenter(center);
    center[2] = _z * m_img->info().pixdim[3];
    m_sagittalWidget->getCrossLine()->setCenter(center);
    m_sagittalWidget->getImageViewer()->Render();
    //----------------------------------------------------------
    m_coronalWidget->getCrossLine()->getCenter(center);
    center[2] = _z * m_img->info().pixdim[3];
    m_coronalWidget->getCrossLine()->setCenter(center);
    m_coronalWidget->getImageViewer()->Render();
}

void img_Viewer::setWindowLevel(double _window, double _level)
{
    m_axialWidget->setWindowLevel(_window, _level);
    m_coronalWidget->setWindowLevel(_window, _level);
    m_sagittalWidget->setWindowLevel(_window, _level);
}

void img_Viewer::setCrossLineMode(bool mode)
{
    m_axialWidget->setCrossLineMode(mode);
    m_coronalWidget->setCrossLineMode(mode);
    m_sagittalWidget->setCrossLineMode(mode);
}

void img_Viewer::setAxesOpen(bool mode)
{
    m_axes->SetVisibility(mode);
    m_3DSlice->Render();
}

void img_Viewer::setAnlsImgOpacity(int _value)
{
    m_axialWidget->setLabelOpacity(_value);
    m_coronalWidget->setLabelOpacity(_value);
    m_sagittalWidget->setLabelOpacity(_value);
}

void img_Viewer::reset3D()
{
    //观察位置
    this->m_render->GetActiveCamera()->SetPosition(
        m_img->info().dim[1]*m_img->info().pixdim[1] / 2,
        m_img->info().dim[2]*m_img->info().pixdim[2] / 2, 1200
    );
    //观察视角
    this->m_render->GetActiveCamera()->SetViewUp(0, 0, 0);
    //观察点
    this->m_render->GetActiveCamera()->SetFocalPoint(
        m_img->info().dim[1]*m_img->info().pixdim[1] / 2,
        m_img->info().dim[2]*m_img->info().pixdim[2] / 2,
        m_img->info().dim[3]*m_img->info().pixdim[3] / 2);
    this->m_render->ResetCameraClippingRange();
    m_3DSlice->Render();
}

void img_Viewer::init3DWidget()
{
    m_3DSlice->AddRenderer(m_render);
    m_axialWidget->getImagePlaneWidget()->SetCurrentRenderer(m_render);
    m_axialWidget->getImagePlaneWidget()->SetInteractor(m_3DSlice->GetInteractor());
    m_coronalWidget->getImagePlaneWidget()->SetCurrentRenderer(m_render);
    m_coronalWidget->getImagePlaneWidget()->SetInteractor(m_3DSlice->GetInteractor());
    m_sagittalWidget->getImagePlaneWidget()->SetCurrentRenderer(m_render);
    m_sagittalWidget->getImagePlaneWidget()->SetInteractor(m_3DSlice->GetInteractor());
    m_axes->SetXAxisLabelText("x");
    m_axes->SetYAxisLabelText("y");
    m_axes->SetZAxisLabelText("z");
    m_axes->SetVisibility(false);
    m_render->AddActor(m_axes);
}

void img_Viewer::initCallback()
{
    m_callback->widget[0] = m_axialWidget;
    m_callback->widget[1] = m_coronalWidget;
    m_callback->widget[2] = m_sagittalWidget;
    m_axialWidget->getImageViewer()->AddObserver(
        vtkResliceImageViewer::SliceChangedEvent, m_callback);
    m_coronalWidget->getImageViewer()->AddObserver(
        vtkResliceImageViewer::SliceChangedEvent, m_callback);
    m_sagittalWidget->getImageViewer()->AddObserver(
        vtkResliceImageViewer::SliceChangedEvent, m_callback);
    //---------------------------------------------------------------------------------
    m_axialWidget->getDefaultStyle()->AddObserver(
        vtkCommand::WindowLevelEvent, m_callback);
    m_coronalWidget->getDefaultStyle()->AddObserver(
        vtkCommand::WindowLevelEvent, m_callback);
    m_sagittalWidget->getDefaultStyle()->AddObserver(
        vtkCommand::WindowLevelEvent, m_callback);
    //---------------------------------------------------------------------------------
}

void img_Viewer::initConnect()
{
    connect(m_axialWidget->getCrossLineStyle(), vtkCrossLineStyle::centerChange, this,
    [&]() {
        double center[3];
        m_axialWidget->getCrossLine()->getCenter(center);
        //----------------------------------------------------
        m_sagittalWidget->setCenter(center, m_axialWidget->getType());
        m_coronalWidget->setCenter(center, m_axialWidget->getType());
    });
    connect(m_coronalWidget->getCrossLineStyle(), vtkCrossLineStyle::centerChange, this,
    [&]() {
        double center[3];
        m_coronalWidget->getCrossLine()->getCenter(center);
        //----------------------------------------------------
        m_sagittalWidget->setCenter(center, m_coronalWidget->getType());
        m_axialWidget->setCenter(center, m_coronalWidget->getType());
    });
    connect(m_sagittalWidget->getCrossLineStyle(), vtkCrossLineStyle::centerChange, this,
    [&]() {
        double center[3];
        m_sagittalWidget->getCrossLine()->getCenter(center);
        //----------------------------------------------------
        m_coronalWidget->setCenter(center, m_sagittalWidget->getType());
        m_axialWidget->setCenter(center, m_sagittalWidget->getType());
    });
}

void img_Viewer::getCurrentPosition(int position[3])
{
    position[m_axialWidget->getType()] = m_axialWidget->getImageViewer()->GetSlice();
    position[m_coronalWidget->getType()] = m_coronalWidget->getImageViewer()->GetSlice();
    position[m_sagittalWidget->getType()] = m_sagittalWidget->getImageViewer()->GetSlice();
}

short img_Viewer::getCurrentPix()
{
    int position[3];
    getCurrentPosition(position);
    return *static_cast<short*>(m_img->image()->GetScalarPointer(position));
}

vtkCallback *img_Viewer::getCallBack()
{
    return m_callback;
}

img_Widget *img_Viewer::getAxilaWidget()
{
    return m_axialWidget;
}

img_Widget *img_Viewer::getCoronalWidget()
{
    return m_coronalWidget;
}

img_Widget *img_Viewer::getSagittalWidget()
{
    return m_sagittalWidget;
}

img_Viewer::~img_Viewer()
{
}
